extern crate rand;

use rand::{Rng, thread_rng};
use rand::distributions::{Uniform, Distribution, Normal, Standard};
use rand::distributions::Alphanumeric;

extern crate algo;
use algo::sort;

fn main() {
    let mut rng = thread_rng();

    let n1: u8 = rng.gen();
    let n2: u16 = rng.gen();
    println!("Random u8: {}", n1);
    println!("Random u16: {}", n2);
    println!("Random u32: {}", rng.gen::<u32>());
    println!("Random i32: {}", rng.gen::<i32>());
    println!("Random float: {}", rng.gen::<f64>());
    let  c = rng.gen::<char>();
    println!("Random char: {}, {:?}", &c, &c);

    println!("range(0-10): {}", rng.gen_range(0, 10) );
    println!("range(0.0 - 10.0): {}", rng.gen_range(0.0, 10.0));

    let die = Uniform::from(1..7);
    loop {
    	let throw = die.sample(&mut rng);
    	println!("Roll the die: {}", throw);
    	if throw == 6 {
    		break;
    	}
    }

    let normal = Normal::new(2.0, 3.0);
    let v = normal.sample(&mut rng);
    println!("{} is from a N(2,9) distribution", v);


    let rand_tuple = rng.gen::<(i32, bool, f64)>();
    let rand_point: Point = rng.gen();
    println!("Random tuple: {:?}", rand_tuple);
    println!("Random Point: {:?}", rand_point);

    let rand_string: String = thread_rng().sample_iter(&Alphanumeric)
    				.take(30).collect();

    println!("the random string is: {}", rand_string);

    println!("random passwd: {}", gen_random_passwd());

    sort::test();
}

#[derive(Debug)]
struct Point {
	x: i32,
	y: i32,
}

impl Distribution<Point> for Standard {
	fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Point {
		let (rand_x, rand_y) = rng.gen();
		Point{
			x: rand_x,
			y: rand_y,
		}
	}
}

fn gen_random_passwd() -> String {
	const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
    abcdefghijklmnopqrstuvwxyz\
    0123456789)(*&^%$#@!~";

    let mut rng = thread_rng();
    let password: Option<String> = (0..30)
    		.map(|_| Some(*rng.choose(CHARSET)? as char))
    		.collect();
    if let Some(s) = password {
    	s
    } else {
    	String::new()
    }
}

